----------------------------------------------------------------------------------------------------------------------------------
--[[

     通用数据储存库，用来储存各种 【文本】数据

    com:AddOverwriteDamageMultiplierFn(inst,function(target,damage)        
        return damage * 1.5
    end)


]]--
----------------------------------------------------------------------------------------------------------------------------------
local hutao_com_fire_damage = Class(function(self, inst)
    self.inst = inst
    ----------------------------------------------
    ---
        self.DataTable = {}
        self.TempTable = {}
        self._onload_fns = {}
        self._onsave_fns = {}
    ----------------------------------------------
    ---
        self.low_sanity = 0.35
    ----------------------------------------------
    --- 倍增器
        -- 乘法倍增器
        self.externaldamagemultipliers = SourceModifierList(self.inst)
        -- 覆盖倍增器
        self.__overwrite_damage_multipliers_fns = {}
        self.__overwrite_damage_multiplier_remove_event = function(temp_inst)
            self:RemoveOverwriteDamageMultiplierFn(temp_inst)
        end
        -- 加法倍增器
        self.__additive_multipliers = {}
        self.__additive_multipliers_remove_event = function(temp_inst)
            self:RemoveAdditiveMultiplier(temp_inst)
        end
    ----------------------------------------------

end,
nil,
{

})
------------------------------------------------------------------------------------------------------------------------------
----- 倍增器
    --- 乘法倍增器
    function hutao_com_fire_damage:AddMultiplier(inst,value)
        self.externaldamagemultipliers:SetModifier(inst,value)
    end
    function hutao_com_fire_damage:RemoveMultiplier(inst)
        self.externaldamagemultipliers:RemoveModifier(inst)
    end
    function hutao_com_fire_damage:GetMultiplier()
        return self.externaldamagemultipliers:Get()
    end
    --- 覆盖倍增器
    function hutao_com_fire_damage:AddOverwriteDamageMultiplierFn(inst,fn)
        if self.__overwrite_damage_multipliers_fns[inst] ~= nil then
            self:RemoveOverwriteDamageMultiplierFn(inst)
        end
        self.__overwrite_damage_multipliers_fns[inst] = fn
        inst:ListenForEvent("onremove",self.__overwrite_damage_multiplier_remove_event)
    end
    function hutao_com_fire_damage:RemoveOverwriteDamageMultiplierFn(inst)
        local new_table = {}
        for k,v in pairs(self.__overwrite_damage_multipliers_fns) do
            if k ~= inst then
                new_table[k] = v
            end
        end
        self.__overwrite_damage_multipliers_fns = new_table
        inst:RemoveEventCallback("onremove",self.__overwrite_damage_multiplier_remove_event)
    end
    --- 加法倍增器
    function hutao_com_fire_damage:AddAdditiveMultiplier(inst,value)
        -- if TUNING.HUTAO_DEBUGGING_MODE then
        --     print("+++ 火伤",inst,value)
        -- end
        if self.__additive_multipliers[inst] ~= nil then
            self:RemoveAdditiveMultiplier(inst)
        end
        self.__additive_multipliers[inst] = value
        inst:ListenForEvent("onremove",self.__additive_multipliers_remove_event)
    end
    function hutao_com_fire_damage:RemoveAdditiveMultiplier(inst)
        -- if TUNING.HUTAO_DEBUGGING_MODE then
        --     print("--- 火伤 移除",inst,self.__additive_multipliers[inst])
        -- end
        local new_table = {}
        for k,v in pairs(self.__additive_multipliers) do
            if k ~= inst then
                new_table[k] = v
            end
        end
        self.__additive_multipliers = new_table
        inst:RemoveEventCallback("onremove",self.__additive_multipliers_remove_event)
    end
    function hutao_com_fire_damage:GetAdditiveMultipliers()
        local additive_mult = 0
        for temp_inst,temp_value in pairs(self.__additive_multipliers) do
            if temp_inst and temp_inst:IsValid() then
                additive_mult = additive_mult + temp_value
            end
        end
        return additive_mult
    end
    --- 所有倍增器结算。
    function hutao_com_fire_damage:GetMult(target,damage)
        --[[
        天赋【高等元素论】：beyond_the_world
            胡桃的火焰伤害（其实就是引魂火）对潮湿单位造成1.5倍伤害，
            对冰霜单位造成双倍伤害，
            对冰冻单位造成3倍伤害解除霜冻状态。
            引魂火伤害对梦魇单位造成双倍伤害
        ]]
        local mult = self.externaldamagemultipliers:Get() -- 乘法倍增器
        --- 覆盖倍增器
        for temp_inst,temp_fn in pairs(self.__overwrite_damage_multipliers_fns) do
            if temp_inst and temp_inst:IsValid() then
                damage = temp_fn(target,damage) or damage
            end
        end
        --- 加法倍增器
        local additive_mult = self:GetAdditiveMultipliers()
        --- 天赋树
        if self.inst.components.hutao_com_talent_tree and 
            self.inst.components.hutao_com_talent_tree:IsUnlocked("beyond_the_world") then
                --- 潮湿
                if target.GetIsWet and target:GetIsWet() then
                    mult = mult * 1.5
                end
                --- 冰霜
                if target.components.freezable then
                    if target.components.freezable:IsFrozen() then
                        mult = mult * 3
                        target.components.freezable:Unfreeze()
                    elseif (target.components.freezable.coldness or 0) > 0 then
                        mult = mult * 2
                    end                
                end
                --- 梦魇
                if target:HasOneOfTags("nightmarecreature","shadow","shadow_aligned") then
                    mult = mult * 2
                end
        end
        return mult * damage* additive_mult
    end
------------------------------------------------------------------------------------------------------------------------------
----- 造成目标燃烧伤害
    function hutao_com_fire_damage:BurnTarget(target)
        --- 生成的隐藏法杖，用于执行燃烧逻辑。进行延迟删除。
        local red_staff = self.__temp_fire_staff
        if red_staff == nil or not red_staff:IsValid() then
            red_staff = SpawnPrefab("firestaff")
        end
        self.__temp_fire_staff = red_staff
        --- 隐藏武器,和屏蔽一些参数
        red_staff:Hide()
        red_staff:AddTag("NOCLICK")
        red_staff:AddTag("NOBLOCK")
        self.inst:AddChild(red_staff)
        red_staff.Physics:Stop()    --- 停掉物理引擎。
        red_staff.Physics:Teleport(0,10,0)
        red_staff.Transform:SetPosition(0,10,0)
        --- 执行燃烧逻辑
        local onattack_red = red_staff.components.weapon.onattack
        if type(onattack_red) == "function" then
            pcall(onattack_red,red_staff,self.inst,target,true)
        end
        --- 恢复耐久
        if red_staff.components.finiteuses then
            red_staff.components.finiteuses:SetPercent(1)
        end
        --- 延迟移除
        if red_staff.__remove_task == nil then
            red_staff.__remove_task = red_staff:DoTaskInTime(5,red_staff.Remove)
        end
    end
    function hutao_com_fire_damage:DoFireDamage(target,damage,with_burning)
        if target and target.___is_hutao_DoFireDamage_flag then -- 避免死循环
            return false
        end
        if target and target.components.health and not target.components.health:IsDead() then
            target.___is_hutao_DoFireDamage_flag = true -- 避免死循环

            damage = self:GetMult(target,damage)
            local target_health_before = target.components.health:GetPercent()
            target.components.health:DoFireDamage(damage, self.inst, true)
            if with_burning or (self.inst.components.sanity:GetPercent() < self.low_sanity) then
                self:BurnTarget(target)
            end
            local target_health_after = target.components.health:GetPercent()
            if target_health_after > 0 then
                target:PushEvent("attacked", { attacker = self.inst, damage = math.abs(damage)})                   
                self.inst:PushEvent("onhitother",{target = target, damage = math.abs(damage)})
            elseif target_health_before > target_health_after and target_health_after then
                self.inst:PushEvent("killed", { victim = target, attacker = self.inst })
            end

            target.___is_hutao_DoFireDamage_flag = nil -- 避免死循环
            return true
        end
        return false
    end
------------------------------------------------------------------------------------------------------------------------------
----- onload/onsave 函数
    function hutao_com_fire_damage:AddOnLoadFn(fn)
        if type(fn) == "function" then
            table.insert(self._onload_fns, fn)
        end
    end
    function hutao_com_fire_damage:ActiveOnLoadFns()
        for k, temp_fn in pairs(self._onload_fns) do
            temp_fn(self)
        end
    end
    function hutao_com_fire_damage:AddOnSaveFn(fn)
        if type(fn) == "function" then
            table.insert(self._onsave_fns, fn)
        end
    end
    function hutao_com_fire_damage:ActiveOnSaveFns()
        for k, temp_fn in pairs(self._onsave_fns) do
            temp_fn(self)
        end
    end
------------------------------------------------------------------------------------------------------------------------------
----- 数据读取/储存

    function hutao_com_fire_damage:Get(index,default)
        if index then
            return self.DataTable[index] or default
        end
        return nil or default
    end
    function hutao_com_fire_damage:Set(index,theData)
        if index then
            self.DataTable[index] = theData
        end
    end

    function hutao_com_fire_damage:Add(index,num,min,max)
        if index then
            if min and max then
                local ret = (self.DataTable[index] or 0) + ( num or 0 )
                ret = math.clamp(ret,min,max)
                self.DataTable[index] = ret
                return ret
            else
                self.DataTable[index] = (self.DataTable[index] or 0) + ( num or 0 )
                return self.DataTable[index]
            end
        end
        return 0
    end
------------------------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------------------------
    function hutao_com_fire_damage:OnSave()
        self:ActiveOnSaveFns()
        local data =
        {
            DataTable = self.DataTable
        }
        return next(data) ~= nil and data or nil
    end

    function hutao_com_fire_damage:OnLoad(data)
        if data.DataTable then
            self.DataTable = data.DataTable
        end
        self:ActiveOnLoadFns()
    end
------------------------------------------------------------------------------------------------------------------------------
return hutao_com_fire_damage







